package server.gui;

import java.util.ArrayList;
import java.util.Iterator;

import server.LogException;
import server.interfaces.ExceptionObserver;

/**
 * <h1>Class ExceptionBrowser</h1>
 *
 * Provides a view to display exceptions happened in the system.
 *
 * @author Tomas
 * @date March 9 2009
 */
public class ExceptionBrowser extends javax.swing.JFrame implements ExceptionObserver{

    /**
	 * Required
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * Initializes a window to show Exceptions.
	 */
	public ExceptionBrowser() {
        initComponents();
        this.setLocationRelativeTo(null);
        LogException.getInstance().subscribe(this);
    }

	/**
	 * Initializes all the window components.
	 */
    private void initComponents() {

        exceptionPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        exceptionList = new javax.swing.JList();
        detailsPanel = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        detailsText = new javax.swing.JTextArea();
        menuBar = new javax.swing.JMenuBar();
        exceptionMenu = new javax.swing.JMenu();
        clearButton = new javax.swing.JMenuItem();
        sep1 = new javax.swing.JSeparator();
        exitButton = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Parlanchin Exception Browser");
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });
        
        exceptionPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Exceptions"));

        exceptionList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                exceptionListMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(exceptionList);

        javax.swing.GroupLayout exceptionPanelLayout = new javax.swing.GroupLayout(exceptionPanel);
        exceptionPanel.setLayout(exceptionPanelLayout);
        exceptionPanelLayout.setHorizontalGroup(
            exceptionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(exceptionPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)
                .addContainerGap())
        );
        exceptionPanelLayout.setVerticalGroup(
            exceptionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(exceptionPanelLayout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE)
                .addContainerGap())
        );

        detailsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Details"));

        detailsText.setColumns(20);
        detailsText.setEditable(false);
        detailsText.setLineWrap(true);
        detailsText.setRows(5);
        detailsText.setWrapStyleWord(true);
        detailsText.setAutoscrolls(true);
        jScrollPane2.setViewportView(detailsText);

        javax.swing.GroupLayout detailsPanelLayout = new javax.swing.GroupLayout(detailsPanel);
        detailsPanel.setLayout(detailsPanelLayout);
        detailsPanelLayout.setHorizontalGroup(
            detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(detailsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 308, Short.MAX_VALUE)
                .addContainerGap())
        );
        detailsPanelLayout.setVerticalGroup(
            detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(detailsPanelLayout.createSequentialGroup()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 397, Short.MAX_VALUE)
                .addContainerGap())
        );

        exceptionMenu.setText("Exception");

        clearButton.setText("Clear Exceptions");
        clearButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearButtonActionPerformed(evt);
            }
        });
        exceptionMenu.add(clearButton);
        exceptionMenu.add(sep1);

        exitButton.setText("Exit");
        exitButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitButtonActionPerformed(evt);
            }
        });
        exceptionMenu.add(exitButton);

        menuBar.add(exceptionMenu);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(exceptionPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(detailsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(detailsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(exceptionPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        pack();
    }

    /**
     * Clear the exceptions.
     * 
     * @param evt
     */
    private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {

    	LogException.getInstance().clear();
    	detailsText.setText("");
    	
    }

    /**
     * Closes the window.
     * 
     * @param evt
     */
    private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {
        
    	closeWindow();
    	
    }
    
    /**
     * Closes the window.
     * 
     * @param evt
     */
    private void formWindowClosing(java.awt.event.WindowEvent evt) {                                   
        
    	closeWindow();
    	
    }
    
    /**
     * Closes the window.
     */
    private void closeWindow(){
    	
    	LogException.getInstance().unsubscribe(this);
    	this.dispose();
    	
    }
    
    /**
     * Displays the details of the selected exception in the exception list.
     * 
     * @param evt
     */
    private void exceptionListMouseClicked(java.awt.event.MouseEvent evt) {
        
    	int pos = exceptionList.getSelectedIndex();
    	
    	Exception e = LogException.getInstance().getException(pos);
    	
    	if(e != null){
    		String message = e.getMessage() + "\n\n";
    		StackTraceElement[] stackTrace = e.getStackTrace();
    		for(int i = 0; i < stackTrace.length; i++){
    			message += "\t" + stackTrace[i].toString() + "\n";
    		}
    		
    		detailsText.setText(message);
    	}
    	
    }

    private javax.swing.JMenuItem clearButton;
    private javax.swing.JPanel detailsPanel;
    private javax.swing.JTextArea detailsText;
    private javax.swing.JList exceptionList;
    private javax.swing.JMenu exceptionMenu;
    private javax.swing.JPanel exceptionPanel;
    private javax.swing.JMenuItem exitButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JSeparator sep1;

	@Override
	/**
	 * @see server.interfaces.ExceptionObserver
	 */
	public void updateExceptions() {
		
		LogException log = LogException.getInstance();
		Iterator<Exception> it = log.getExceptions();
		ArrayList<String> exceptions = new ArrayList<String>();
		
		while(it.hasNext()){
			Exception e = it.next();
			String exceptionName = e.getClass().toString();
			exceptions.add(exceptionName);
		}
		
		String[] names = new String[exceptions.size()];
		exceptions.toArray(names);
		final String[] content = names;
		exceptionList.setModel(new javax.swing.AbstractListModel() {
			private static final long serialVersionUID = 1L;
			
			String[] strings = content;
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
	}

}
